import { roomFunc } from "./room.util"
import SnapLine3 from "../three/SnapLine3"
import SnapVector3 from "../three/SnapVector3"
import * as THREE from "three"
import ModelColliderTarget from "../mesh/ModelColliderTarget"
var Se = {
  1: "SnapPoint",
  2: "SnapLine",
  3: "AxisAny",
  4: "AxisX",
  5: "AxisY",
  6: "AxisZ",
  7: "Mesh",
  8: "RoomMesh",
  9: "LinePoint",
  10: "LineSegment",
  AxisAny: 3,
  AxisX: 4,
  AxisY: 5,
  AxisZ: 6,
  LinePoint: 9,
  LineSegment: 10,
  Mesh: 7,
  RoomMesh: 8,
  SnapLine: 2,
  SnapPoint: 1
}
const Re = (e: THREE.Intersection) => e && "face" in e && void 0 !== e.face && roomFunc.hasFloorId(e.object)
const Ce = (e: THREE.Intersection) => e && "isLineOctreeIntersection" in e && roomFunc.hasFloorId(e["object"])
export default class ConstrainedHit {
  constraint: number
  point: THREE.Vector3
  normal: THREE.Vector3
  source: THREE.Intersection
  distance: number
  object: THREE.Mesh
  roomId: string
  floorId: string
  featureType: number
  _point: THREE.Vector3
  constructor(e: THREE.Intersection, t: number, i?) {
    this.constraint = t
    this.point = new THREE.Vector3()
    this.normal = new THREE.Vector3()
    Re(e) ? this.updateFromIntersection(e, t) : Ce(e) && i && this.updateFromSnapIntersection(e, t, i), (this.source = e)
  }
  updatePoint(e) {
    return this.point.copy(e), this.source.point.copy(e), this
  }
  updateFromIntersection(e: THREE.Intersection, t: number) {
    this.source = e
    this.updateContents(t, e.point, e.face.normal, e.distance, e.object)
    return this
  }
  updateFromSnapIntersection(e, t, i) {
    this.source = e
    this.updateContents(t, e.point, i, e.distance, e.object)
    return this
  }
  copy({ constraint: e, point: t, normal: i, distance: s, object: n }) {
    this.updateContents(e, t, i, s, n)
  }
  clone() {
    return new ConstrainedHit(this.source, this.constraint)
  }
  updateContents(e: number, t: THREE.Vector3, i: THREE.Vector3, s: number, n: any) {
    this.constraint = e
    this.point = this.point.copy(t)
    this._point = this.point.copy(t)
    this.normal = this.normal.copy(i)
    this.distance = s
    this.object = n
    roomFunc.hasRoomId(n)
      ? ((this.roomId = n.roomId), (this.floorId = n.floorId))
      : roomFunc.hasFloorId(n) && ((this.floorId = n.floorId), (this.roomId = null))
    this.featureType = (e => {
      if (e)
        return "featureType" in e && void 0 !== e.featureType
          ? e.featureType
          : e instanceof THREE.Vector3 || e instanceof SnapVector3
          ? Se.SnapPoint
          : roomFunc.isRoomMesh(e)
          ? Se.RoomMesh
          : e instanceof ModelColliderTarget
          ? Se.Mesh
          : e instanceof THREE.Line3 || e instanceof SnapLine3
          ? Se.SnapLine
          : void 0
    })(n)
  }
}
